<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Flow Chat</title>
  <style>
  * {
    margin: 0;
    padding: 0;
  }

  #app {
    margin: 10px;
  }

  .state {
    display: flex;
    flex-direction: row;
  }

  .state .item {
    display: flex;
    flex-direction: row;
    text-align: center;
    margin-right: 10px;
  }

  .state .item .icon {
    width: 20px;
    height: 20px;
    margin: 0 5px;
    border-radius: 0;
  }

  .state .item .text {
    font-size: 14px;
  }

  ul li {
    display: inline;
  }

  ul li::before {
    content: '  ';
    /*left: 0;*/
    padding: 0 7px;
    margin: 0 5px;
    color: #2c3e50;
    font-size: 12px;
    background-color: #2c3e50;
  }

  .config {
    padding: 10px 5px;
  }

  .title {
    font-weight: bold;
    font-size: 20px;
  }

  .config .items .item {
    display: flex;
    flex-direction: row;
    margin: 10px 0;
  }

  .config .items .item label {
    width: 80px;
  }

  .themes {
    margin-top: 20px;
    display: flex;
    flex-direction: row;
  }

  .themes div {
    padding: 10px 20px;
    margin-right: 20px;
    cursor: pointer;
  }

  .theme1 {
    background-color: white;
    color: black;
    border: solid 1px black;
    border-radius: 5px;
  }

  .theme2 {
    background-color: #cef3eb;
    color: black;
    border: solid 1px #13c69d;
    border-radius: 5px;
  }

  .theme3 {
    background-color: #fde0e0;
    color: black;
    border: solid 1px #f87878;
    border-radius: 5px;
  }

  .theme4 {
    background-color: #ebebeb;
    color: black;
    border: solid 1px #999999;
    border-radius: 5px;
  }

  #flowChatCanvas {
    border: 1px solid #eee;
  }

  </style>
</head>
<body>
<div id="app">
  <div class="state">
    <div class="item">
      <div class="icon theme4"></div>
      <div class="text">未执行</div>
    </div>
    <div class="item">
      <div class="icon theme2"></div>
      <div class="text">已通过</div>
    </div>
    <div class="item">
      <div class="icon theme3"></div>
      <div class="text">当前节点</div>
    </div>
  </div>
  <div class="config">
    <h1 class="title">配置</h1>
    <div class="items">
      <div class="item">
        <label>边框</label>
        <input id="borderColorInput" type="text" value="black">
      </div>
      <div class="item">
        <label>背景</label>
        <input id="backgroundColorInput" type="text" value="white">
      </div>
      <div class="item">
        <label>文字颜色</label>
        <input id="textColorInput" type="text" value="black">
      </div>
    </div>
    <h1 class="title">主题</h1>
    <div class="themes">
      <div id="1" class="theme1">主题1</div>
      <div id="2" class="theme2">主题2</div>
      <div id="3" class="theme3">主题3</div>
      <div id="4" class="theme4">主题3</div>
    </div>
  </div>
  <canvas id="flowChatCanvas"></canvas>

</div>
<script src="rect.js"></script>
<script type="application/javascript">

let themes = [
  {id: '1', borderColor: 'black', backgroundColor: 'white', textColor: 'black'},
  {id: '2', borderColor: '#13c69d', backgroundColor: '#cef3eb', textColor: 'black'},
  {id: '3', borderColor: '#f87878', backgroundColor: '#fde0e0', textColor: 'black'},
  {id: '4', borderColor: '#999999', backgroundColor: '#ebebeb', textColor: 'black'},
]

window.onload = function () {
  addEventListener();
  let canvas = document.getElementById('flowChatCanvas')
  let ctx = canvas.getContext('2d')
  canvas.width = 1440;
  canvas.height = 500;
  // 解决模糊问题
  let dpr = window.devicePixelRatio; // 假设dpr为2
  // 获取css的宽高
  let {width: cssWidth, height: cssHeight} = canvas.getBoundingClientRect();
  // 根据dpr，扩大canvas画布的像素，使1个canvas像素和1个物理像素相等
  canvas.width = dpr * cssWidth;
  canvas.height = dpr * cssHeight;
  // 由于画布扩大，canvas的坐标系也跟着扩大，如果按照原先的坐标系绘图内容会缩小
  // 所以需要将绘制比例放大
  ctx.scale(dpr, dpr);
  let rects = []
  let rectOption = {
    location: {
      x: 140, y: 30
    },
    width: 138,
    height: 70,
    background: {
      color: 'white'
    },
    texts: [
      {
        color: 'black',
        content: '发起人'
      },
      {
        color: 'black',
        content: '张三'
      }
    ],
    border: {
      width: 1,
      color: 'black'
    },
  }

  function drawRect() {
    rects = []
    rectOption.location = {x: 140, y: 30}
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    for (let i = 0; i < 5; i++) {
      rectOption.location.x = rectOption.location.x + (i == 0 ? 0 : 250)
      console.log(rectOption)
      rects.push(new Rect(rectOption))
    }
    // 画矩形
    rects.forEach(rect => rect.draw(ctx))
    // 画连接线
    for (let i = 0; i < rects.length; i++) {
      if (i < rects.length - 1) {
        let rect = rects[i]
        let rect1 = rects[i + 1]
        drawConnectLine(rect.x + rect.w, rect.cy, rect1.x, rect1.cy, rectOption.border.color)
      }
    }
  }

  drawRect()

  function drawConnectLine(x, y, x1, y1, color) {
    ctx.beginPath()
    ctx.strokeStyle = color
    ctx.fillStyle = color
    ctx.moveTo(x, y)
    ctx.lineTo(x1 - 10, y1)
    // 画箭头小三角型
    ctx.moveTo(x1 - 10, y - 5)
    ctx.lineTo(x1 - 10, y + 5)
    ctx.lineTo(x1, y)
    ctx.closePath()
    ctx.fill()
    ctx.stroke()
  }

  function addEventListener() {
    // 监听表单改变事件
    let borderColorInput = document.getElementById('borderColorInput')
    borderColorInput.addEventListener('change', (e) => {
      rectOption.border.color = e.target.value
      drawRect()
    })
    let backgroundColorInput = document.getElementById('backgroundColorInput')
    backgroundColorInput.addEventListener('change', (e) => {
      rectOption.background.color = e.target.value
      drawRect()
    })
    let textColorInput = document.getElementById('textColorInput')
    textColorInput.addEventListener('change', (e) => {
      rectOption.texts.forEach(text => text.color = e.target.value)
      drawRect()
    })
    // 监听主题切换事件
    let themesEls = document.getElementsByClassName('themes')[0].querySelectorAll('div')
    themesEls.forEach(theme => {
      console.log(theme)
      theme.addEventListener('click', (e) => {
        let themeId = e.target.id
        let themeConfig = themes.find(th => th.id == themeId)
        rectOption.border.color = themeConfig.borderColor
        borderColorInput.value = themeConfig.borderColor
        rectOption.background.color = themeConfig.backgroundColor
        backgroundColorInput.value = themeConfig.backgroundColor
        rectOption.texts.forEach(text => text.color = themeConfig.textColor)
        textColorInput.value = themeConfig.textColor
        drawRect()
      })
    })

  }

}
</script>
</body>
</html>
